package com.ruoyi.system.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.system.dao.HomeDao;
import com.ruoyi.system.dao.LargeScreenDao;
import com.ruoyi.system.domain.dto.QuaStatisticsDto;
import com.ruoyi.system.domain.po.BlsZlInfo;
import com.ruoyi.system.domain.po.BlsZlInfoExample;
import com.ruoyi.system.domain.vo.HomeVo;
import com.ruoyi.system.domain.vo.LargeScreenVo;
import com.ruoyi.system.domain.vo.QuaStatisticsVo;
import com.ruoyi.system.mapper.BlsZlInfoMapper;
import com.ruoyi.system.service.HomeService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import static cn.hutool.core.date.DateField.ERA;
import static com.ruoyi.common.constant.UserConstants.QuestionCode.*;

@Service
@Slf4j
public class HomeServiceImpl implements HomeService {

    @Resource
    private HomeDao homeDao;
    @Resource
    private BlsZlInfoMapper blsZlInfoMapper;
    @Resource
    private LargeScreenDao largeScreenDao;

    public QuaStatisticsDto.QueryPatient getDto(QuaStatisticsDto.QueryPatient dto){
        if (dto.getStartTime() != null && dto.getEndTime() != null) {
            Date endTime = dto.getEndTime();
            Date startTime = dto.getStartTime();
            if (startTime.compareTo(endTime) > 0) {
                dto.setEndTime(startTime);
                dto.setStartTime(endTime);
            }
        }
        return dto;
    }

    @Override
    public List<HomeVo.Bltj> queryBltj(QuaStatisticsDto.QueryPatient dto) throws ParseException {
        dto = getDto(dto);
        List<HomeVo.Bltj> result = new ArrayList<>();
        List<QuaStatisticsVo.NumResult> query = homeDao.queryNum(dto.getTimeType(), dto.getStartTime(), dto.getEndTime());
        if (CollectionUtil.isNotEmpty(query)) {
            for (QuaStatisticsVo.NumResult numResult : query) {
                HomeVo.Bltj bltj = new HomeVo.Bltj();
                bltj.setZynczhzs(numResult.getTotal());
//                bltj.setXDate(numResult.getYear() + "-" + numResult.getChild());
                switch (dto.getTimeType()) {
                    case 0:
                        // 3. 分割年份和周数
                        String yearStr = numResult.getPeriod().substring(0, 4);
                        String weekStr = numResult.getPeriod().substring(4, 6);
                        Date date = weekToDay(yearStr + "-" + weekStr);
                        bltj.setDate(date);
                        bltj.setXDate(DateUtil.format(bltj.getDate(), "yyyy-MM-dd"));
                        break;
                    case 1:
                        bltj.setDate(DateUtil.parse(numResult.getPeriod(), "yyyy-MM"));
                        bltj.setXDate(DateUtil.format(bltj.getDate(), "yyyy-MM"));
                        break;
                    case 2:
                        // 1. 正则验证格式（如 2024Q3）
                        Pattern pattern = Pattern.compile("^(\\d{4})Q([1-4])$");
                        Matcher matcher = pattern.matcher(numResult.getPeriod());
                        if (!matcher.find()) {
                            throw new IllegalArgumentException("输入格式必须为 YYYYQN（例如 2024Q3）");
                        }
                        String year = matcher.group(1);
                        int quarter = Integer.parseInt(matcher.group(2));

                        // 计算季度对应的最后一个月（Q1=3月, Q2=6月...）
                        int month = quarter * 3;
                        bltj.setDate(DateUtil.parse(String.format("%s-%02d", year, month), "yyyy-MM"));
                        bltj.setXDate(DateUtil.format(bltj.getDate(), "yyyy-MM"));
                        break;
                    case 3:
                        bltj.setDate(DateUtil.parse(numResult.getPeriod() + "", "yyyy"));
                        bltj.setXDate(numResult.getPeriod());
                        break;
                    default:
                        break;
                }
                result.add(bltj);
            }
            return result;
        }

        List<QuaStatisticsVo.NcxLvList> list = homeDao.selectNcxLv(dto.getTimeType(), dto.getStartTime(), dto.getEndTime());
        if (CollectionUtil.isEmpty(list)) {
            return new ArrayList<>();
        }
        Map<String, List<QuaStatisticsVo.NcxLvList>> map = list.stream().collect(Collectors.groupingBy(QuaStatisticsVo.NcxLvList::getDateTime));
        log.info("list:{}", list);
        for (Map.Entry<String, List<QuaStatisticsVo.NcxLvList>> entry : map.entrySet()) {
            if (StrUtil.isEmpty(entry.getKey())) {
                continue;
            }
            Map<Long, List<QuaStatisticsVo.NcxLvList>> collect = entry.getValue().stream().collect(Collectors.groupingBy(QuaStatisticsVo.NcxLvList::getFirstAidId));

            HomeVo.Bltj bltj = new HomeVo.Bltj();
            int zynczhzs = bltj.getZynczhzs();
            bltj.setZynczhzs(zynczhzs + collect.size());
            bltj.setTotal(zynczhzs + collect.size());
            Date date = new Date();
            String xDate = "";
            switch (dto.getTimeType()) {
                case 1:
                    date = DateUtil.parse(entry.getKey(), "yyyy-MM");
                    xDate = DateUtil.format(date, "yyyy-MM");
                    break;
                case 3:
                    date = DateUtil.parse(entry.getKey(), "yyyy");
                    xDate = DateUtil.format(date, "yyyy");
                    break;
                case 2:
                    Date rysj = entry.getValue().get(0).getCreateTime();
                    Calendar cal = Calendar.getInstance();
                    cal.setTime(rysj);
                    String str = "";
                    if ("1".equals(entry.getKey())) {
                        str = "-01-01";
                    } else if ("2".equals(entry.getKey())) {
                        str = "-04-01";
                    } else if ("3".equals(entry.getKey())) {
                        str = "-07-01";
                    } else if ("4".equals(entry.getKey())) {
                        str = "-10-01";
                    }
                    date = DateUtil.parse(cal.get(Calendar.YEAR) + str, "yyyy-MM");
                    xDate = DateUtil.format(date, "yyyy-MM");
                    break;
//                    date = DateUtil.parse(entry.getKey(), "yyyy-MM");
//                    xDate = DateUtil.format(date, "yyyy-MM");
//                    break;
                case 4:
                    date = DateUtil.parse(entry.getKey(), "yyyy");
                    xDate = DateUtil.format(date, "yyyy");
                    break;
                default:
                    break;
            }
            if (dto.getTimeType() == 0) {
                bltj.setDate(weekToDay(entry.getKey()));
                bltj.setXDate(entry.getKey());
            } else {
                bltj.setDate(date);
                bltj.setXDate(xDate);
            }
            result.add(bltj);
        }
        if (CollectionUtil.isEmpty(result)) {
            return result;
        }
        List<HomeVo.Bltj> resultList = result.stream().sorted(Comparator.comparing(HomeVo.Bltj::getDate)).collect(Collectors.toList());
        List<HomeVo.Bltj> list1 = completionBltj(dto.getTimeType(), resultList, dto.getStartTime(), dto.getEndTime());
        return list1.stream().sorted(Comparator.comparing(HomeVo.Bltj::getDate)).collect(Collectors.toList());
    }

    /**
     * 根据周数查日期
     * 慎用
     *
     * @param time
     * @return
     */
    public static Date weekToDay(String time) {
        String[] split = time.split("-");
        if (split.length != 2) {
            return null;
        }
        Integer year = Integer.parseInt(split[0]);
        Integer week = Integer.parseInt(split[1]);
        Date date = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.set(year, 0, 1);
        int dayOfWeek = 7 - calendar.get(Calendar.DAY_OF_WEEK) + 2;//算出第一周还剩几天 +1是因为1号是1天
        week = week - 2;//周数减去第一周再减去要得到的周
        calendar.add(Calendar.DAY_OF_YEAR, week * 7 + dayOfWeek);
        date = calendar.getTime();
//        calendar.add(Calendar.DAY_OF_YEAR, 6);
//        date.add(new SimpleDateFormat("yyyy-MM-dd").format(calendar.getTime()));
        return date;
    }

    private List<HomeVo.Bltj> completionBltj(Integer timeType, List<HomeVo.Bltj> xgzlResults, Date startTime, Date endTime) throws ParseException {

        //时间补齐
        Date startDate;
        Date endDate;
        DateField dateField = ERA;
        int offset = 0;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");

        switch (timeType) {
            case 0:
                //起始周 2
                offset = 1;
                dateField = DateField.WEEK_OF_YEAR;
                if (startTime == null) {
                    startDate = new DateTime(xgzlResults.get(0).getDate());
                    endDate = new DateTime(xgzlResults.get(xgzlResults.size() - 1).getDate());
                } else {
                    sdf = new SimpleDateFormat("yyyy-MM-dd");
                    startDate = sdf.parse(sdf.format(startTime));
                    endDate = sdf.parse(sdf.format(endTime));
                }
                break;
            case 1:
                offset = 1;
                dateField = DateField.MONTH;
                if (startTime == null) {
                    startDate = xgzlResults.get(0).getDate();
                    endDate = xgzlResults.get(xgzlResults.size() - 1).getDate();
                } else {
                    sdf = new SimpleDateFormat("yyyy-MM");
                    startDate = sdf.parse(sdf.format(startTime));
                    endDate = sdf.parse(sdf.format(endTime));
                }
                break;
            case 2:
                dateField = DateField.MONTH;
                offset = 3;
                if (startTime == null) {
                    startDate = xgzlResults.get(0).getDate();
                    endDate = xgzlResults.get(xgzlResults.size() - 1).getDate();
                } else {
                    sdf = new SimpleDateFormat("yyyy-MM-dd");
                    startDate = sdf.parse(sdf.format(startTime));
                    endDate = sdf.parse(sdf.format(endTime));
                }
                break;
            case 3:
                dateField = DateField.YEAR;
                offset = 1;
                if (startTime == null) {
                    startDate = xgzlResults.get(0).getDate();
                    endDate = xgzlResults.get(xgzlResults.size() - 1).getDate();
                } else {
                    sdf = new SimpleDateFormat("yyyy");
                    startDate = sdf.parse(sdf.format(startTime));
                    endDate = sdf.parse(sdf.format(endTime));
                }
                break;
            case 4:
                offset = 1;
                dateField = DateField.DAY_OF_MONTH;
                if (startTime == null) {
                    startDate = new DateTime(xgzlResults.get(0).getDate());
                    endDate = new DateTime(xgzlResults.get(xgzlResults.size() - 1).getDate());
                } else {
                    sdf = new SimpleDateFormat("yyyy-MM-dd");
                    startDate = sdf.parse(sdf.format(startTime));
                    endDate = sdf.parse(sdf.format(endTime));
                }
                break;
            default:
                if (startTime == null) {
                    startDate = new DateTime();
                    endDate = new DateTime();
                } else {
                    startDate = startTime;
                    endDate = endTime;
                }
                break;
        }
        List<Date> dateList = xgzlResults.stream().map(HomeVo.Bltj::getDate).collect(Collectors.toList());
        if (!dateList.contains(startDate)) {
            HomeVo.Bltj result = new HomeVo.Bltj();
            result.setDate(startDate);
            result.setTotal(0);
            result.setZynczhzs(0);
            result.setXDate(sdf.format(startDate));
            xgzlResults.add(result);
        }
        while (DateUtil.compare(startDate, endDate) < 0) {
            startDate = DateUtil.offset(startDate, dateField, offset);
            if (dateList.contains(startDate)) {
                continue;
            }
            HomeVo.Bltj result = new HomeVo.Bltj();
            result.setDate(startDate);
            result.setTotal(0);
            result.setZynczhzs(0);
            result.setXDate(sdf.format(startDate));
            xgzlResults.add(result);
        }
        return xgzlResults;
    }

    private List<HomeVo.NldfbData> completionNlfb(Integer timeType, List<HomeVo.NldfbData> xgzlResults, Date startTime, Date endTime) throws ParseException {

        //时间补齐
        Date startDate;
        Date endDate;
        DateField dateField = ERA;
        int offset = 0;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");

        switch (timeType) {
            case 0:
                //起始周 2
                offset = 1;
                dateField = DateField.WEEK_OF_YEAR;
//                if (startTime == null) {
                startDate = xgzlResults.get(0).getDate();
                endDate = xgzlResults.get(xgzlResults.size() - 1).getDate();
//                }
                sdf = new SimpleDateFormat("yyyy-ww");
//                else {
//                    sdf = new SimpleDateFormat("yyyy-MM-dd");
//                    startDate = sdf.parse(sdf.format(startTime));
//                    endDate = sdf.parse(sdf.format(endTime));
//                }
                break;
            case 1:
                offset = 1;
                dateField = DateField.MONTH;
                if (startTime == null) {
                    startDate = xgzlResults.get(0).getDate();
                    endDate = xgzlResults.get(xgzlResults.size() - 1).getDate();
                } else {
                    sdf = new SimpleDateFormat("yyyy-MM");
                    startDate = sdf.parse(sdf.format(startTime));
                    endDate = sdf.parse(sdf.format(endTime));
                }
                break;
            case 2:
                dateField = DateField.MONTH;
                offset = 3;
                if (startTime == null) {
                    startDate = xgzlResults.get(0).getDate();
                    endDate = xgzlResults.get(xgzlResults.size() - 1).getDate();
                } else {
                    sdf = new SimpleDateFormat("yyyy-MM-dd");
                    startDate = sdf.parse(sdf.format(startTime));
                    endDate = sdf.parse(sdf.format(endTime));
                }
                break;
            case 3:
                dateField = DateField.YEAR;
                offset = 1;
                if (startTime == null) {
                    startDate = xgzlResults.get(0).getDate();
                    endDate = xgzlResults.get(xgzlResults.size() - 1).getDate();
                } else {
                    sdf = new SimpleDateFormat("yyyy");
                    startDate = sdf.parse(sdf.format(startTime));
                    endDate = sdf.parse(sdf.format(endTime));
                }
                break;
            case 4:
                offset = 1;
                dateField = DateField.DAY_OF_MONTH;
                if (startTime == null) {
                    startDate = new DateTime(xgzlResults.get(0).getDate());
                    endDate = new DateTime(xgzlResults.get(xgzlResults.size() - 1).getDate());
                } else {
                    sdf = new SimpleDateFormat("yyyy-MM-dd");
                    startDate = sdf.parse(sdf.format(startTime));
                    endDate = sdf.parse(sdf.format(endTime));
                }
                break;
            default:
                if (startTime == null) {
                    startDate = new DateTime();
                    endDate = new DateTime();
                } else {
                    startDate = startTime;
                    endDate = endTime;
                }
                break;
        }
        List<String> timeList = new ArrayList<>();
        for (HomeVo.NldfbData xgzlResult : xgzlResults) {
            timeList.add(xgzlResult.getXDate());
        }
        List<Date> dateList = xgzlResults.stream().map(HomeVo.NldfbData::getDate).collect(Collectors.toList());
        if (!dateList.contains(startDate)) {
            HomeVo.NldfbData result = new HomeVo.NldfbData();
            result.setDate(startDate);
            result.setTotal(0);
            result.setXDate(sdf.format(startDate));
            xgzlResults.add(result);
        }
        while (DateUtil.compare(startDate, endDate) < 0) {
            startDate = DateUtil.offset(startDate, dateField, offset);
            String format = sdf.format(startDate);
            if (timeList.contains(format)) {
                continue;
            }
            HomeVo.NldfbData result = new HomeVo.NldfbData();
            result.setDate(startDate);
            result.setTotal(0);
            result.setXDate(sdf.format(startDate));
            xgzlResults.add(result);
        }
        return xgzlResults;
    }

    @Override
    public HomeVo.BltjResult queryBltjResult(QuaStatisticsDto.QueryPatient dto) {
        dto = getDto(dto);
        HomeVo.BltjResult bltjResult = new HomeVo.BltjResult();
        List<QuaStatisticsVo.NcxLvList> list = homeDao.selectNcxLv(dto.getTimeType(), dto.getStartTime(), dto.getEndTime());
        if (CollectionUtil.isEmpty(list)) {
            return bltjResult;
        }
        Map<Long, List<QuaStatisticsVo.NcxLvList>> map = list.stream().collect(Collectors.groupingBy(QuaStatisticsVo.NcxLvList::getFirstAidId));
        bltjResult.setTotal(map.size());
        bltjResult.setZynczhzs(map.size());
        return bltjResult;
    }

    @Override
    public HomeVo.Xbfb queryXbtjResult(QuaStatisticsDto.QueryPatient dto) {
        dto = getDto(dto);
        HomeVo.Xbfb xbfb = new HomeVo.Xbfb();
        int mjznczhzs = 0;
        int zynczhzs = 0;
        int total = 0;
        List<QuaStatisticsVo.NcxLvList> list = homeDao.selectNcxLv(dto.getTimeType(), dto.getStartTime(), dto.getEndTime());
        if (CollectionUtil.isEmpty(list)) {
            return xbfb;
        }
        Map<String, List<QuaStatisticsVo.NcxLvList>> map = list.stream().collect(Collectors.groupingBy(QuaStatisticsVo.NcxLvList::getDateTime));
        total = map.size();
        for (Map.Entry<String, List<QuaStatisticsVo.NcxLvList>> entry : map.entrySet()) {
            if (StrUtil.isEmpty(entry.getKey())) {
                continue;
            }
            List<QuaStatisticsVo.NcxLvList> value = entry.getValue();
            if (CollectionUtil.isEmpty(value)) {
                continue;
            }
            for (QuaStatisticsVo.NcxLvList qsfxList : value) {
                if (PERSON_GENDER.getKey().equals(qsfxList.getCode())) {
                    if ("1".equals(qsfxList.getAnswer())) {
                        mjznczhzs += 1;
                    } else {
                        zynczhzs += 1;
                    }
                }
            }
            xbfb.setZynczhzs(xbfb.getZynczhzs() + zynczhzs);
            xbfb.setMjznczhzs(xbfb.getMjznczhzs() + mjznczhzs);
        }
        xbfb.setTotal(total);
        return xbfb;
    }

    @Override
    public List<HomeVo.Xbfb> queryXbtj(QuaStatisticsDto.QueryPatient dto) throws ParseException {
        dto = getDto(dto);
        List<HomeVo.Xbfb> result = new ArrayList<>();
        int mjznczhzs = 0;
        int zynczhzs = 0;
        int total = 0;
        List<QuaStatisticsVo.SexResult> sexResults = homeDao.querySex(dto.getTimeType(), dto.getStartTime(), dto.getEndTime());
        if (CollectionUtil.isNotEmpty(sexResults)) {
            //循环创建返回格式
            for (QuaStatisticsVo.SexResult numResult : sexResults) {
                HomeVo.Xbfb xbfb = new HomeVo.Xbfb();
                if (numResult.getSex() == 1) {
                    xbfb.setMjznczhzs(numResult.getTotal());
                } else {
                    xbfb.setZynczhzs(numResult.getTotal());
                }
                xbfb.setXDate(numResult.getYear() + "-" + numResult.getChild());
                switch (dto.getTimeType()) {
                    case 0:
                        // 3. 分割年份和周数
                        String yearStr = numResult.getPeriod().substring(0, 4);
                        String weekStr = numResult.getPeriod().substring(4, 6);
                        Date date = weekToDay(yearStr + "-" + weekStr);
                        xbfb.setDate(date);
                        xbfb.setXDate(DateUtil.format(xbfb.getDate(), "yyyy-MM-dd"));
                        break;
                    case 1:
                        xbfb.setDate(DateUtil.parse(numResult.getPeriod(), "yyyy-MM"));
                        xbfb.setXDate(DateUtil.format(xbfb.getDate(), "yyyy-MM"));
                        break;
                    case 2:
                        // 1. 正则验证格式（如 2024Q3）
                        Pattern pattern = Pattern.compile("^(\\d{4})Q([1-4])$");
                        Matcher matcher = pattern.matcher(numResult.getPeriod());
                        if (!matcher.find()) {
                            throw new IllegalArgumentException("输入格式必须为 YYYYQN（例如 2024Q3）");
                        }
                        String year = matcher.group(1);
                        int quarter = Integer.parseInt(matcher.group(2));

                        // 计算季度对应的最后一个月（Q1=3月, Q2=6月...）
                        int month = quarter * 3;
                        xbfb.setDate(DateUtil.parse(String.format("%s-%02d", year, month), "yyyy-MM"));
                        xbfb.setXDate(DateUtil.format(xbfb.getDate(), "yyyy-MM"));
                        break;
                    case 3:
                        xbfb.setDate(DateUtil.parse(numResult.getPeriod() + "", "yyyy"));
                        xbfb.setXDate(numResult.getPeriod());
                        break;
                    default:
                        break;
                }
                result.add(xbfb);
            }
            if (CollectionUtil.isNotEmpty(result)) {
                Map<Date, List<HomeVo.Xbfb>> map = result.stream().collect(Collectors.groupingBy(HomeVo.Xbfb::getDate));
                List<HomeVo.Xbfb> returnList = new ArrayList<>();
                for (Map.Entry<Date, List<HomeVo.Xbfb>> entry : map.entrySet()) {
                    HomeVo.Xbfb xbfb = entry.getValue().get(0);
                    if (entry.getValue().size() > 1) {
                        HomeVo.Xbfb xbfb1 = entry.getValue().get(1);
                        if (xbfb.getMjznczhzs() > 0) {
                            xbfb.setZynczhzs(xbfb1.getZynczhzs());
                        } else {
                            xbfb.setMjznczhzs(xbfb1.getMjznczhzs());
                        }
                        returnList.add(xbfb);
                    } else {
                        returnList.add(xbfb);
                    }
                }
                return returnList.stream().sorted(Comparator.comparing(HomeVo.Xbfb::getDate)).collect(Collectors.toList());
            }
        }

        List<QuaStatisticsVo.NcxLvList> list = homeDao.selectNcxLv(dto.getTimeType(), dto.getStartTime(), dto.getEndTime());
        if (CollectionUtil.isEmpty(list)) {
            return result;
        }
        Map<String, List<QuaStatisticsVo.NcxLvList>> map = list.stream().collect(Collectors.groupingBy(QuaStatisticsVo.NcxLvList::getDateTime));
        total = map.size();
        for (Map.Entry<String, List<QuaStatisticsVo.NcxLvList>> entry : map.entrySet()) {
            if (StrUtil.isEmpty(entry.getKey())) {
                continue;
            }
            HomeVo.Xbfb xbfb = new HomeVo.Xbfb();
            List<QuaStatisticsVo.NcxLvList> value = entry.getValue();
            if (CollectionUtil.isEmpty(value)) {
                continue;
            }
            Map<Long, List<QuaStatisticsVo.NcxLvList>> collect = value.stream().collect(Collectors.groupingBy(QuaStatisticsVo.NcxLvList::getFirstAidId));
            for (Map.Entry<Long, List<QuaStatisticsVo.NcxLvList>> entry1 : collect.entrySet()) {
                for (QuaStatisticsVo.NcxLvList qsfxList : entry1.getValue()) {
                    if (qsfxList.getSex() != null) {
                        if (qsfxList.getSex() == 1) {
                            mjznczhzs += 1;
                            break;
                        } else {
                            zynczhzs += 1;
                            break;
                        }
                    }
                }
            }
            Date date = new Date();
            String xDate = "";
            switch (dto.getTimeType()) {
                case 1:
                    date = DateUtil.parse(entry.getKey(), "yyyy-MM");
                    xDate = DateUtil.format(date, "yyyy-MM");
                    break;
                case 3:
                    date = DateUtil.parse(entry.getKey(), "yyyy");
                    xDate = DateUtil.format(date, "yyyy");
                    break;
                case 2:
                    Date rysj = entry.getValue().get(0).getCreateTime();
                    Calendar cal = Calendar.getInstance();
                    cal.setTime(rysj);
                    String str = "";
                    if ("1".equals(entry.getKey())) {
                        str = "-01-01";
                    } else if ("2".equals(entry.getKey())) {
                        str = "-04-01";
                    } else if ("3".equals(entry.getKey())) {
                        str = "-07-01";
                    } else if ("4".equals(entry.getKey())) {
                        str = "-10-01";
                    }
                    date = DateUtil.parse(cal.get(Calendar.YEAR) + str, "yyyy-MM");
                    xDate = DateUtil.format(date, "yyyy-MM");
                    break;
//                    date = DateUtil.parse(entry.getKey(), "yyyy-MM");
//                    xDate = DateUtil.format(date, "yyyy-MM");
//                    break;
                case 4:
                    date = DateUtil.parse(entry.getKey(), "yyyy");
                    xDate = DateUtil.format(date, "yyyy");
                    break;
                default:
                    break;
            }
            if (dto.getTimeType() == 0) {
                xbfb.setDate(weekToDay(entry.getKey()));
                xbfb.setXDate(entry.getKey());
            } else {
                xbfb.setDate(date);
                xbfb.setXDate(xDate);
            }
//            xbfb.setDate(date);
//            xbfb.setXDate(xDate);
            xbfb.setZynczhzs(zynczhzs);
            xbfb.setTotal(total);
            xbfb.setMjznczhzs(mjznczhzs);
            result.add(xbfb);
        }
        if (CollectionUtil.isEmpty(result)) {
            return result;
        }
        List<HomeVo.Xbfb> resultList = result.stream().sorted(Comparator.comparing(HomeVo.Xbfb::getDate)).collect(Collectors.toList());
        List<HomeVo.Xbfb> list1 = completionXbfb(dto.getTimeType(), resultList, dto.getStartTime(), dto.getEndTime());
        return list1.stream().sorted(Comparator.comparing(HomeVo.Xbfb::getDate)).collect(Collectors.toList());
    }

    private List<HomeVo.Xbfb> completionXbfb(Integer timeType, List<HomeVo.Xbfb> xgzlResults, Date startTime, Date endTime) throws ParseException {

        //时间补齐
        Date startDate;
        Date endDate;
        DateField dateField = ERA;
        int offset = 0;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");

        switch (timeType) {
            case 0:
                //起始周 2
                offset = 1;
                dateField = DateField.WEEK_OF_YEAR;
                if (startTime == null) {
                    startDate = new DateTime(xgzlResults.get(0).getDate());
                    endDate = new DateTime(xgzlResults.get(xgzlResults.size() - 1).getDate());
                } else {
                    sdf = new SimpleDateFormat("yyyy-MM-dd");
                    startDate = sdf.parse(sdf.format(startTime));
                    endDate = sdf.parse(sdf.format(endTime));
                }
                break;
            case 1:
                offset = 1;
                dateField = DateField.MONTH;
                if (startTime == null) {
                    startDate = xgzlResults.get(0).getDate();
                    endDate = xgzlResults.get(xgzlResults.size() - 1).getDate();
                } else {
                    sdf = new SimpleDateFormat("yyyy-MM");
                    startDate = sdf.parse(sdf.format(startTime));
                    endDate = sdf.parse(sdf.format(endTime));
                }
                break;
            case 2:
                dateField = DateField.MONTH;
                offset = 3;
                if (startTime == null) {
                    startDate = xgzlResults.get(0).getDate();
                    endDate = xgzlResults.get(xgzlResults.size() - 1).getDate();
                } else {
                    sdf = new SimpleDateFormat("yyyy-MM-dd");
                    startDate = sdf.parse(sdf.format(startTime));
                    endDate = sdf.parse(sdf.format(endTime));
                }
                break;
            case 3:
                dateField = DateField.YEAR;
                offset = 1;
                if (startTime == null) {
                    startDate = xgzlResults.get(0).getDate();
                    endDate = xgzlResults.get(xgzlResults.size() - 1).getDate();
                } else {
                    sdf = new SimpleDateFormat("yyyy");
                    startDate = sdf.parse(sdf.format(startTime));
                    endDate = sdf.parse(sdf.format(endTime));
                }
                break;
            case 4:
                offset = 1;
                dateField = DateField.DAY_OF_MONTH;
                if (startTime == null) {
                    startDate = new DateTime(xgzlResults.get(0).getDate());
                    endDate = new DateTime(xgzlResults.get(xgzlResults.size() - 1).getDate());
                } else {
                    sdf = new SimpleDateFormat("yyyy-MM-dd");
                    startDate = sdf.parse(sdf.format(startTime));
                    endDate = sdf.parse(sdf.format(endTime));
                }
                break;
            default:
                if (startTime == null) {
                    startDate = new DateTime();
                    endDate = new DateTime();
                } else {
                    startDate = startTime;
                    endDate = endTime;
                }
                break;
        }
        List<Date> dateList = xgzlResults.stream().map(HomeVo.Xbfb::getDate).collect(Collectors.toList());
        if (!dateList.contains(startDate)) {
            HomeVo.Xbfb result = new HomeVo.Xbfb();
            result.setDate(startDate);
            result.setTotal(0);
            result.setZynczhzs(0);
            result.setXDate(sdf.format(startDate));
            xgzlResults.add(result);
        }
        while (DateUtil.compare(startDate, endDate) < 0) {
            startDate = DateUtil.offset(startDate, dateField, offset);
            if (dateList.contains(startDate)) {
                continue;
            }
            HomeVo.Xbfb result = new HomeVo.Xbfb();
            result.setDate(startDate);
            result.setTotal(0);
            result.setZynczhzs(0);
            result.setXDate(sdf.format(startDate));
            xgzlResults.add(result);
        }
        return xgzlResults;
    }

    @Override
    public HomeVo.Nldfb queryNlfb(QuaStatisticsDto.QueryPatient dto) {
        dto = getDto(dto);
        HomeVo.Nldfb nldfb = new HomeVo.Nldfb();

        List<QuaStatisticsVo.SexResult> sexResults = homeDao.queryAge(dto.getTimeType(), dto.getStartTime(), dto.getEndTime());
        if (CollectionUtil.isNotEmpty(sexResults)) {
            int num1 = 0, num2 = 0, num3 = 0, num4 = 0, total = 0;
            for (QuaStatisticsVo.SexResult sexResult : sexResults) {
                num1 += sexResult.getNum1();
                num2 += sexResult.getNum2();
                num3 += sexResult.getNum3();
                num4 += sexResult.getNum4();
            }
            nldfb.setNum1(num1);
            nldfb.setNum2(num2);
            nldfb.setNum3(num3);
            nldfb.setNum4(num4);
            nldfb.setTotal(num1 + num2 + num3 + num4);
            return nldfb;
        }

        List<QuaStatisticsVo.NcxLvList> list = homeDao.selectNcxLv(dto.getTimeType(), dto.getStartTime(), dto.getEndTime());
        if (CollectionUtil.isEmpty(list)) {
            return nldfb;
        }
        int num1 = 0;
        int num2 = 0;
        int num3 = 0;
        int num4 = 0;
        int total = 0;
        Map<Long, List<QuaStatisticsVo.NcxLvList>> map = list.stream().collect(Collectors.groupingBy(QuaStatisticsVo.NcxLvList::getFirstAidId));
        total = map.size();
        for (Map.Entry<Long, List<QuaStatisticsVo.NcxLvList>> entry : map.entrySet()) {
            List<QuaStatisticsVo.NcxLvList> value = entry.getValue();
            if (CollectionUtil.isEmpty(value)) {
                break;
            }
            if (value.get(0).getZyAge() > 0) {
                int age = value.get(0).getZyAge();
                if (age > 0 && age <= 19) {
                    num1 += 1;
                }
                if (age >= 20 && age <= 39) {
                    num2 += 1;
                }
                if (age >= 40 && age <= 59) {
                    num3 += 1;
                }
                if (age >= 60 && age <= 79) {
                    num4 += 1;
                }
            }
        }
        nldfb.setNum1(num1);
        nldfb.setNum2(num2);
        nldfb.setNum3(num3);
        nldfb.setNum4(num4);
        nldfb.setTotal(total);
        return nldfb;
    }

    @Override
    public List<HomeVo.NldfbData> queryNlfbList(QuaStatisticsDto.QueryPatient dto) throws ParseException {
        dto = getDto(dto);
        List<HomeVo.NldfbData> result = new ArrayList<>();
        List<QuaStatisticsVo.SexResult> sexResults = homeDao.queryAge(dto.getTimeType(), dto.getStartTime(), dto.getEndTime());
        if (CollectionUtil.isNotEmpty(sexResults)) {
            for (QuaStatisticsVo.SexResult numResult : sexResults) {
                HomeVo.NldfbData nldfbData = new HomeVo.NldfbData();
                nldfbData.setNum1(numResult.getNum1());
                nldfbData.setNum2(numResult.getNum2());
                nldfbData.setNum3(numResult.getNum3());
                nldfbData.setNum4(numResult.getNum4());
                switch (dto.getTimeType()) {
                    case 0:
                        // 3. 分割年份和周数
                        String yearStr = numResult.getPeriod().substring(0, 4);
                        String weekStr = numResult.getPeriod().substring(4, 6);
                        Date date = weekToDay(yearStr + "-" + weekStr);
                        nldfbData.setDate(date);
                        nldfbData.setXDate(DateUtil.format(nldfbData.getDate(), "yyyy-MM-dd"));
                        break;
                    case 1:
                        nldfbData.setDate(DateUtil.parse(numResult.getPeriod(), "yyyy-MM"));
                        nldfbData.setXDate(DateUtil.format(nldfbData.getDate(), "yyyy-MM"));
                        break;
                    case 2:
                        // 1. 正则验证格式（如 2024Q3）
                        Pattern pattern = Pattern.compile("^(\\d{4})Q([1-4])$");
                        Matcher matcher = pattern.matcher(numResult.getPeriod());
                        if (!matcher.find()) {
                            throw new IllegalArgumentException("输入格式必须为 YYYYQN（例如 2024Q3）");
                        }
                        String year = matcher.group(1);
                        int quarter = Integer.parseInt(matcher.group(2));

                        // 计算季度对应的最后一个月（Q1=3月, Q2=6月...）
                        int month = quarter * 3;
                        nldfbData.setDate(DateUtil.parse(String.format("%s-%02d", year, month), "yyyy-MM"));
                        nldfbData.setXDate(DateUtil.format(nldfbData.getDate(), "yyyy-MM"));
                        break;
                    case 3:
                        nldfbData.setDate(DateUtil.parse(numResult.getPeriod() + "", "yyyy"));
                        nldfbData.setXDate(numResult.getPeriod());
                        break;
                    default:
                        break;
                }
                result.add(nldfbData);
            }
            return result;
        }

        List<QuaStatisticsVo.NcxLvList> list = homeDao.selectNcxLv(dto.getTimeType(), dto.getStartTime(), dto.getEndTime());
        if (CollectionUtil.isEmpty(list)) {
            return new ArrayList<>();
        }
        Map<String, List<QuaStatisticsVo.NcxLvList>> map = list.stream().collect(Collectors.groupingBy(QuaStatisticsVo.NcxLvList::getDateTime));
        for (Map.Entry<String, List<QuaStatisticsVo.NcxLvList>> entry : map.entrySet()) {
            if (StrUtil.isEmpty(entry.getKey())) {
                continue;
            }
            HomeVo.NldfbData nldfb = new HomeVo.NldfbData();
            int num1 = 0, num2 = 0, num3 = 0, num4 = 0, total = 0;

            Map<Long, List<QuaStatisticsVo.NcxLvList>> collect = entry.getValue().stream().collect(Collectors.groupingBy(QuaStatisticsVo.NcxLvList::getFirstAidId));
            total = collect.size();
            for (Map.Entry<Long, List<QuaStatisticsVo.NcxLvList>> en : collect.entrySet()) {
                List<QuaStatisticsVo.NcxLvList> value = en.getValue();
                if (CollectionUtil.isEmpty(value)) {
                    continue;
                }
//                for (QuaStatisticsVo.NcxLvList qsfxList : value) {
                if (value.get(0).getZyAge() > 0) {
                    int age = value.get(0).getZyAge();
                    if (age > 0 && age <= 19) {
                        num1 += 1;
                    }
                    if (age >= 20 && age <= 39) {
                        num2 += 1;
                    }
                    if (age >= 40 && age <= 59) {
                        num3 += 1;
                    }
                    if (age >= 60 && age <= 79) {
                        num4 += 1;
                    }
                }
//                }
                Date date = new Date();
                String xDate = entry.getKey();
                switch (dto.getTimeType()) {
                    case 1:
                        date = DateUtil.parse(entry.getKey(), "yyyy-MM");
                        xDate = DateUtil.format(date, "yyyy-MM");
                        break;
                    case 3:
                        date = DateUtil.parse(entry.getKey(), "yyyy");
                        xDate = DateUtil.format(date, "yyyy");
                        break;
                    case 2:
                        Date rysj = entry.getValue().get(0).getCreateTime();
                        Calendar cal = Calendar.getInstance();
                        cal.setTime(rysj);
                        String str = "";
                        if ("1".equals(entry.getKey())) {
                            str = "-01-01";
                        } else if ("2".equals(entry.getKey())) {
                            str = "-04-01";
                        } else if ("3".equals(entry.getKey())) {
                            str = "-07-01";
                        } else if ("4".equals(entry.getKey())) {
                            str = "-10-01";
                        }
                        date = DateUtil.parse(cal.get(Calendar.YEAR) + str, "yyyy-MM");
                        xDate = DateUtil.format(date, "yyyy-MM");
                        break;
//                    date = DateUtil.parse(entry.getKey(), "yyyy-MM");
//                    xDate = DateUtil.format(date, "yyyy-MM");
//                    break;
                    case 4:
                        date = DateUtil.parse(entry.getKey(), "yyyy");
                        xDate = DateUtil.format(date, "yyyy");
                        break;
                    default:
                        break;
                }
                if (dto.getTimeType() == 0) {
                    nldfb.setDate(weekToDay(entry.getKey()));
                    nldfb.setXDate(entry.getKey());
                } else {
                    nldfb.setDate(date);
                    nldfb.setXDate(xDate);
                }

            }
            nldfb.setNum1(num1);
            nldfb.setNum2(num2);
            nldfb.setNum3(num3);
            nldfb.setNum4(num4);
            nldfb.setTotal(total);
            result.add(nldfb);
        }
        List<HomeVo.NldfbData> resultList = result.stream().sorted(Comparator.comparing(HomeVo.NldfbData::getDate)).collect(Collectors.toList());
        List<HomeVo.NldfbData> list1 = completionNlfb(dto.getTimeType(), resultList, dto.getStartTime(), dto.getEndTime());
        return list1.stream().sorted(Comparator.comparing(HomeVo.NldfbData::getDate)).collect(Collectors.toList());
    }

    @Override
    public HomeVo.Bzfb queryBzfb(QuaStatisticsDto.QueryPatient dto) throws ParseException {
        dto = getDto(dto);
        HomeVo.Bzfb bzfb = new HomeVo.Bzfb();
        BlsZlInfoExample blsZlInfoExample = new BlsZlInfoExample();
        blsZlInfoExample.createCriteria().andDelFlagEqualTo((byte) 0);
        List<BlsZlInfo> blsZlInfoList = blsZlInfoMapper.selectByExample(blsZlInfoExample);
        if (CollectionUtil.isEmpty(blsZlInfoList)) {
            return bzfb;
        }
        int total = blsZlInfoList.size();
//        int jmrsNum = homeDao.countJmrs(dto.getTimeType(), dto.getStartTime(), dto.getEndTime());
//        int jrztNum = 0;
//        int ncxNum = 0;
//        int lndmNuml = 0;
//        int ceaNum = 0;
//        int casNum = 0;
//        for (BlsZlInfo blsZlInfo : blsZlInfoList) {
//            if (StrUtil.isNotEmpty(blsZlInfo.getSsbm())) {
//                String[] split = blsZlInfo.getSsbm().split(",");
//                for (String s : split) {
//                    if (UserConstants.AISJMRS.contains(s)) {
//                        jmrsNum += 1;
//                    }
//                    if (UserConstants.AISJRZT.contains(s)) {
//                        jrztNum += 1;
//                    }
//                    if (UserConstants.NCX.contains(s)) {
//                        ncxNum += 1;
//                    }
//                    if (UserConstants.LNDML.contains(s)) {
//                        lndmNuml += 1;
//                    }
//                    if (UserConstants.CEA.contains(s)) {
//                        ceaNum += 1;
//                    }
//                    if (UserConstants.CAS.contains(s)) {
//                        casNum += 1;
//                    }
//                }
//            }
//        }
//        bzfb.setCas(new BigDecimal(casNum).divide(new BigDecimal(total), 2, RoundingMode.HALF_UP));
//        bzfb.setJmrs(new BigDecimal(jmrsNum).divide(new BigDecimal(total), 2, RoundingMode.HALF_UP));
//        bzfb.setJrzt(new BigDecimal(jrztNum).divide(new BigDecimal(total), 2, RoundingMode.HALF_UP));
//        bzfb.setCea(new BigDecimal(ceaNum).divide(new BigDecimal(total), 2, RoundingMode.HALF_UP));
//        bzfb.setNcx(new BigDecimal(ncxNum).divide(new BigDecimal(total), 2, RoundingMode.HALF_UP));
//        bzfb.setLndml(new BigDecimal(lndmNuml).divide(new BigDecimal(total), 2, RoundingMode.HALF_UP));
        Integer totalNum;
        int jmrsNum = largeScreenDao.queryNumYearJmrs(null, null);
        int ceaNum = largeScreenDao.queryBlsZlNumByCodes(null, null, UserConstants.CEA);
        int casNum = largeScreenDao.queryBlsZlNumByCodes(null, null, UserConstants.CAS);
        int aisjrztNum = largeScreenDao.queryBlsZlNumByCodes(null, null, UserConstants.AISJRZT);
        int ncxNum = largeScreenDao.queryBlsZlNumByCodes(null, null, UserConstants.NCX);
        int lndmlNum = largeScreenDao.queryBlsZlNumByCodes(null, null, UserConstants.LNDML);

        totalNum = jmrsNum + ceaNum + casNum + aisjrztNum + ncxNum + lndmlNum;



//        bzfb.setLndml(lndmlNum);
//        bzfb.setJrzt(aisjrztNum);
//        bzfb.setCea(ceaNum);
//        bzfb.setCas(casNum);
//        bzfb.setJmrs(jmrsNum);
//        bzfb.setNcx(ncxNum);
        if (totalNum > 0) {
            bzfb.setCas(new BigDecimal(casNum).divide(new BigDecimal(totalNum), 2, RoundingMode.HALF_UP).multiply(new BigDecimal(100)));
            bzfb.setCea(new BigDecimal(ceaNum).divide(new BigDecimal(totalNum), 2, RoundingMode.HALF_UP).multiply(new BigDecimal(100)));
            bzfb.setJmrs(new BigDecimal(jmrsNum).divide(new BigDecimal(totalNum), 2, RoundingMode.HALF_UP).multiply(new BigDecimal(100)));
            bzfb.setLndml(new BigDecimal(lndmlNum).divide(new BigDecimal(totalNum), 2, RoundingMode.HALF_UP).multiply(new BigDecimal(100)));
            bzfb.setJrzt(new BigDecimal(aisjrztNum).divide(new BigDecimal(totalNum), 2, RoundingMode.HALF_UP).multiply(new BigDecimal(100)));
            bzfb.setNcx(new BigDecimal(ncxNum).divide(new BigDecimal(totalNum), 2, RoundingMode.HALF_UP).multiply(new BigDecimal(100)));
        }
        return bzfb;
    }

    @Override
    public List<HomeVo.BzfbTime> queryBfzTime(QuaStatisticsDto.QueryPatient dto) throws ParseException {
        dto = getDto(dto);
        List<HomeVo.BzfbTime> list = new ArrayList<>();
        List<HomeVo.BzfbTime> selectBzfbTime = homeDao.selectBzfbTime(dto.getTimeType(), dto.getStartTime(), dto.getEndTime());
        if (CollectionUtil.isEmpty(selectBzfbTime)) {
            return list;
        }
        Map<String, List<HomeVo.BzfbTime>> collect = selectBzfbTime.stream().collect(Collectors.groupingBy(HomeVo.BzfbTime::getDateTime));
        for (Map.Entry<String, List<HomeVo.BzfbTime>> entry : collect.entrySet()) {
            if (StrUtil.isEmpty(entry.getKey())) {
                continue;
            }
            HomeVo.BzfbTime bzfbTime = new HomeVo.BzfbTime();
            if (CollectionUtil.isEmpty(entry.getValue())) {
                continue;
            }
            int total = entry.getValue().size();
            int jmrsNum = 0;
            int jrztNum = 0;
            int ncxNum = 0;
            int lndmNuml = 0;
            int ceaNum = 0;
            int casNum = 0;
            for (HomeVo.BzfbTime blsZlInfo : entry.getValue()) {
                if (UserConstants.AISJMRS.contains(blsZlInfo.getSsbm())) {
                    jmrsNum += 1;
                }
                if (UserConstants.AISJRZT.contains(blsZlInfo.getSsbm())) {
                    jrztNum += 1;
                }
                if (UserConstants.NCX.contains(blsZlInfo.getSsbm())) {
                    ncxNum += 1;
                }
                if (UserConstants.LNDML.contains(blsZlInfo.getSsbm())) {
                    lndmNuml += 1;
                }
                if (UserConstants.CEA.contains(blsZlInfo.getSsbm())) {
                    ceaNum += 1;
                }
                if (UserConstants.CAS.contains(blsZlInfo.getSsbm())) {
                    casNum += 1;
                }
            }
            bzfbTime.setDateTime(entry.getKey());
            bzfbTime.setJrztNum(jrztNum);
            bzfbTime.setNcxNum(ncxNum);
            bzfbTime.setLndmNuml(lndmNuml);
            bzfbTime.setJmrsNum(jmrsNum);
            bzfbTime.setCasNum(casNum);
            bzfbTime.setCeaNum(ceaNum);

            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-ww");
            Date parse = new Date();
            String key = entry.getKey();
            if (StrUtil.isEmpty(key)) {
                continue;
            }
            switch (dto.getTimeType()) {
                case 0:
                    sdf = new SimpleDateFormat("yyyy-ww");
                    parse = sdf.parse(key);

                    break;
                case 1:
                    sdf = new SimpleDateFormat("yyyy-MM");
                    parse = sdf.parse(key);
                    break;
                case 2:
                    sdf = new SimpleDateFormat("yyyy-MM");
                    List<HomeVo.BzfbTime> dptListList = entry.getValue().stream().sorted(Comparator.comparing(HomeVo.BzfbTime::getDateTime)).collect(Collectors.toList());
                    Date rysj = dptListList.get(0).getRysj();
                    Calendar cal = Calendar.getInstance();
                    cal.setTime(rysj);
                    String str = "";
                    if ("1".equals(key)) {
                        str = "-01-01";
                    } else if ("2".equals(key)) {
                        str = "-04-01";
                    } else if ("3".equals(key)) {
                        str = "-07-01";
                    } else if ("4".equals(key)) {
                        str = "-10-01";
                    }
                    bzfbTime.setDateTime(cal.get(Calendar.YEAR) + str);
                    parse = sdf.parse(cal.get(Calendar.YEAR) + str);
                    break;
                case 3:
                    sdf = new SimpleDateFormat("yyyy");
                    parse = sdf.parse(key);
                    break;
                case 4:
                    sdf = new SimpleDateFormat("yyyy-MM-dd");
                    parse = sdf.parse(key);
                    break;
                default:
                    break;
            }
            bzfbTime.setDate(parse);
            list.add(bzfbTime);
        }
        if (CollectionUtil.isNotEmpty(list)) {
            list = list.stream().sorted(Comparator.comparing(HomeVo.BzfbTime::getDateTime)).collect(Collectors.toList());
            completionBfzTime(dto.getTimeType(), list, dto.getStartTime(), dto.getEndTime());
            list = list.stream().sorted(Comparator.comparing(HomeVo.BzfbTime::getDateTime)).collect(Collectors.toList());
        }
        return list;
    }

    //补充数据
    private List<HomeVo.BzfbTime> completionBfzTime(Integer timeType, List<HomeVo.BzfbTime> list, Date startTime, Date endTime) throws ParseException {
        //时间补齐
        Date startDate;
        Date endDate;
        DateField dateField = ERA;
        int offset = 0;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        switch (timeType) {
            case 0:
                //起始周
                offset = 1;
                dateField = DateField.WEEK_OF_YEAR;
                if (startTime == null) {
                    startDate = new DateTime(list.get(0).getDate());
                    endDate = new DateTime(list.get(list.size() - 1).getDate());
                } else {
                    sdf = new SimpleDateFormat("yyyy-MM-dd");
                    startDate = sdf.parse(sdf.format(startTime));
                    endDate = sdf.parse(sdf.format(endTime));
                }
                break;
            case 1:
                offset = 1;
                dateField = DateField.MONTH;
                sdf = new SimpleDateFormat("yyyy-MM");
                if (startTime == null) {
                    startDate = list.get(0).getDate();
                    endDate = list.get(list.size() - 1).getDate();
                } else {

                    startDate = sdf.parse(sdf.format(startTime));
                    endDate = sdf.parse(sdf.format(endTime));
                }
                break;
            case 2:
                dateField = DateField.MONTH;
                offset = 3;
                sdf = new SimpleDateFormat("yyyy-MM-dd");
                if (startTime == null) {
                    startDate = list.get(0).getDate();
                    endDate = list.get(list.size() - 1).getDate();
                } else {
                    startDate = sdf.parse(sdf.format(startTime));
                    endDate = sdf.parse(sdf.format(endTime));
                }
                break;
            case 3:
                dateField = DateField.YEAR;
                offset = 1;
                sdf = new SimpleDateFormat("yyyy");
                if (startTime == null) {
                    startDate = list.get(0).getDate();
                    endDate = list.get(list.size() - 1).getDate();
                } else {

                    startDate = sdf.parse(sdf.format(startTime));
                    endDate = sdf.parse(sdf.format(endTime));
                }
                break;
            case 4:
                offset = 1;
                dateField = DateField.DAY_OF_MONTH;
                if (startTime == null) {
                    startDate = new DateTime(list.get(0).getDate());
                    endDate = new DateTime(list.get(list.size() - 1).getDate());
                } else {
                    sdf = new SimpleDateFormat("yyyy-MM-dd");
                    startDate = sdf.parse(sdf.format(startTime));
                    endDate = sdf.parse(sdf.format(endTime));
                }
                break;
            default:
                if (startTime == null) {
                    startDate = new DateTime();
                    endDate = new DateTime();
                } else {
                    startDate = startTime;
                    endDate = endTime;
                }
                break;
        }

        List<Date> dateList = new ArrayList<>();
        for (HomeVo.BzfbTime bzfbTime : list) {
            String dateTime = bzfbTime.getDateTime();
            if (StrUtil.isEmpty(dateTime)) {
                continue;
            }
            switch (timeType) {
                case 1:
                    dateList.add(DateUtil.parse(dateTime, "yyyy-MM"));
                    break;
                case 2:
                    dateList.add(DateUtil.parse(dateTime, "yyyy-MM"));
                    break;
                case 4:
                    sdf = new SimpleDateFormat("yyyy-MM-dd");
                    dateList.add(sdf.parse(sdf.format(dateTime)));
                    break;
                case 3:
                    sdf = new SimpleDateFormat("yyyy");
                    dateList.add(sdf.parse(sdf.format(dateTime)));
                    break;
                default:
                    sdf = new SimpleDateFormat("yyyy-MM-dd");
                    dateList.add(sdf.parse(sdf.format(dateTime)));
                    break;
            }
        }
        if (!dateList.contains(startDate)) {
            HomeVo.BzfbTime result = new HomeVo.BzfbTime();
            result.setDate(startDate);
            result.setDateTime(sdf.format(startDate));
            list.add(result);
        }
        while (DateUtil.compare(startDate, endDate) < 0) {
            startDate = DateUtil.offset(startDate, dateField, offset);
            if (dateList.contains(startDate)) {
                continue;
            }
            HomeVo.BzfbTime result = new HomeVo.BzfbTime();
            result.setDate(startDate);
            result.setDateTime(sdf.format(startDate));
            list.add(result);
        }
        return list;
    }

    @Override
    public HomeVo.MjzzdfbTop10 queryMjzzdfbTop10(QuaStatisticsDto.QueryPatient dto) {
        dto = getDto(dto);
        HomeVo.MjzzdfbTop10 bzfbTime = new HomeVo.MjzzdfbTop10();
        List<HomeVo.BzfbTime> selectBzfbTime = homeDao.selectBzfbTime(dto.getTimeType(), dto.getStartTime(), dto.getEndTime());
        if (CollectionUtil.isEmpty(selectBzfbTime)) {
            return bzfbTime;
        }
        int zgwfxhzyfjmxsss = 0;
        int zwmxqcx = 0;
        int nnncx = 0;
        int ngs = 0;
        int ncz = 0;
        int rnqdmdbshxz = 0;
        int dndmbshxz = 0;
        int qtnxgb_jxdml = 0;
        int flyqtcdjbyqdnxgjh = 0;
        int dzxnqxfzxgzhz = 0;

        List<HomeVo.BzfbTime> list = new ArrayList<>();
        for (HomeVo.BzfbTime time : selectBzfbTime) {
            if (time.getDateTime() == null) {
                list.add(time);
            }
        }
        selectBzfbTime.removeAll(list);
        Map<String, List<HomeVo.BzfbTime>> collect = selectBzfbTime.stream().collect(Collectors.groupingBy(HomeVo.BzfbTime::getDateTime));
        for (Map.Entry<String, List<HomeVo.BzfbTime>> entry : collect.entrySet()) {
            if (StrUtil.isEmpty(entry.getKey())) {
                continue;
            }
            if (CollectionUtil.isEmpty(entry.getValue())) {
                continue;
            }
            for (HomeVo.BzfbTime blsZlInfo : entry.getValue()) {
                if (StrUtil.isEmpty(blsZlInfo.getZdbm())) {
                    continue;
                }
                String zdbm = blsZlInfo.getZdbm();
                String s = "";
                String[] split = zdbm.split(".");
                if (split.length > 0) {
                    s = split[0];
                }else {
                    s = zdbm;
                }
                if (UserConstants.ZGWFXHZYFJMXSSS.contains(s)) {
                    zgwfxhzyfjmxsss += 1;
                }
                if (UserConstants.ZWMXQCX.contains(s)) {
                    zwmxqcx += 1;
                }
                if (UserConstants.NNNCX.contains(s)) {
                    nnncx += 1;
                }
                if (UserConstants.NGS.contains(s)) {
                    ngs += 1;
                }
                if (UserConstants.NCZ.contains(s)) {
                    ncz += 1;
                }
                if (UserConstants.RNQDMDBSHXZ.contains(s)) {
                    rnqdmdbshxz += 1;
                }
                if (UserConstants.DNDMBSHXZ.contains(s)) {
                    dndmbshxz += 1;
                }
                if (UserConstants.QTNXGB_JXDML.contains(s)) {
                    qtnxgb_jxdml += 1;
                }
                if (UserConstants.FLYQTCDJBYQDNXGJH.contains(s)) {
                    flyqtcdjbyqdnxgjh += 1;
                }
                if (UserConstants.DZXNQXFZXGZHZ.contains(s)) {
                    dzxnqxfzxgzhz += 1;
                }
            }
        }
        bzfbTime.setDndmbshxz(dndmbshxz);
        bzfbTime.setNgs(ngs);
        bzfbTime.setNcz(ncz);
        bzfbTime.setNnncx(nnncx);
        bzfbTime.setDzxnqxfzxgzhz(dzxnqxfzxgzhz);
        bzfbTime.setFlyqtcdjbyqdnxgjh(flyqtcdjbyqdnxgjh);
        bzfbTime.setRnqdmdbshxz(rnqdmdbshxz);
        bzfbTime.setZwmxqcx(zwmxqcx);
        bzfbTime.setQtnxgb_jxdml(qtnxgb_jxdml);
        bzfbTime.setZgwfxhzyfjmxsss(zgwfxhzyfjmxsss);
        return bzfbTime;
    }

    @Override
    public HomeVo.MjzzdfbTop10 queryZyzdTop10(QuaStatisticsDto.QueryPatient dto) {
        dto = getDto(dto);
        HomeVo.MjzzdfbTop10 bzfbTime = new HomeVo.MjzzdfbTop10();
        List<HomeVo.BzfbTime> selectBzfbTime = homeDao.selectBzfbTime(dto.getTimeType(), dto.getStartTime(), dto.getEndTime());
        if (CollectionUtil.isEmpty(selectBzfbTime)) {
            return bzfbTime;
        }
        List<HomeVo.BzfbTime> list = new ArrayList<>();
        for (HomeVo.BzfbTime time : selectBzfbTime) {
            if (time.getDateTime() == null) {
                list.add(time);
            }
        }
        selectBzfbTime.removeAll(list);
        int zgwfxhzyfjmxsss = 0;
        int zwmxqcx = 0;
        int nnncx = 0;
        int ngs = 0;
        int ncz = 0;
        int rnqdmdbshxz = 0;
        int dndmbshxz = 0;
        int qtnxgb_jxdml = 0;
        int flyqtcdjbyqdnxgjh = 0;
        int dzxnqxfzxgzhz = 0;
        Map<String, List<HomeVo.BzfbTime>> collect = selectBzfbTime.stream().collect(Collectors.groupingBy(HomeVo.BzfbTime::getDateTime));
        for (Map.Entry<String, List<HomeVo.BzfbTime>> entry : collect.entrySet()) {
            if (StrUtil.isEmpty(entry.getKey())) {
                continue;
            }
            if (CollectionUtil.isEmpty(entry.getValue())) {
                continue;
            }

            for (HomeVo.BzfbTime blsZlInfo : entry.getValue()) {
                if (StrUtil.isEmpty(blsZlInfo.getZdbm())) {
                    continue;
                }
                String[] split = blsZlInfo.getZdbm().split(",");
                for (String s : split) {
                    if (StrUtil.isEmpty(s)) {
                        continue;
                    }
                    if (UserConstants.ZGWFXHZYFJMXSSS.equals(s)) {
                        zgwfxhzyfjmxsss += 1;
                    }
                    if (UserConstants.ZWMXQCX.contains(s.split("\\.").length == 0 ? s : s.split("\\.")[0])) {
                        zwmxqcx += 1;
                    }
                    if (UserConstants.NNNCX.contains(s.split("\\.").length == 0 ? s : s.split("\\.")[0])) {
                        nnncx += 1;
                    }
                    if (UserConstants.NGS.contains(s.split("\\.").length == 0 ? s : s.split("\\.")[0])) {
                        ngs += 1;
                    }
                    if (UserConstants.NCZ.contains(s.split("\\.").length == 0 ? s : s.split("\\.")[0])) {
                        ncz += 1;
                    }
                    if (UserConstants.RNQDMDBSHXZ.contains(s.split("\\.").length == 0 ? s : s.split("\\.")[0])) {
                        rnqdmdbshxz += 1;
                    }
                    if (UserConstants.DNDMBSHXZ.contains(s.split("\\.").length == 0 ? s : s.split("\\.")[0])) {
                        dndmbshxz += 1;
                    }
                    if (UserConstants.QTNXGB_JXDML.contains(s.split("\\.").length == 0 ? s : s.split("\\.")[0])) {
                        qtnxgb_jxdml += 1;
                    }
                    if (UserConstants.FLYQTCDJBYQDNXGJH.contains(s.split("\\.").length == 0 ? s : s.split("\\.")[0])) {
                        flyqtcdjbyqdnxgjh += 1;
                    }
                    if (UserConstants.DZXNQXFZXGZHZ.contains(s.split("\\.").length == 0 ? s : s.split("\\.")[0])) {
                        dzxnqxfzxgzhz += 1;
                    }
                }
            }
        }
        bzfbTime.setDndmbshxz(dndmbshxz);
        bzfbTime.setNgs(ngs);
        bzfbTime.setNcz(ncz);
        bzfbTime.setNnncx(nnncx);
        bzfbTime.setDzxnqxfzxgzhz(dzxnqxfzxgzhz);
        bzfbTime.setFlyqtcdjbyqdnxgjh(flyqtcdjbyqdnxgjh);
        bzfbTime.setRnqdmdbshxz(rnqdmdbshxz);
        bzfbTime.setZwmxqcx(zwmxqcx);
        bzfbTime.setQtnxgb_jxdml(qtnxgb_jxdml);
        bzfbTime.setZgwfxhzyfjmxsss(zgwfxhzyfjmxsss);
        return bzfbTime;
    }
}
